package com.wxsm.wechat.core.socket;

import com.wxsm.wechat.core.exception.ServiceException;
import com.wxsm.wechat.dao.AttentionDao;
import com.wxsm.wechat.dao.MessageDao;
import com.wxsm.wechat.model.entity.AttentionEntity;
import com.wxsm.wechat.model.entity.CommentEntity;
import com.wxsm.wechat.model.entity.MessageEntity;
import com.wxsm.wechat.model.enums.MessageTypeEnum;
import com.wxsm.wechat.util.JsonUtil;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created with Yang Huan
 * Date: 2017/6/5
 * Time: 10:26
 */
@Service
@AllArgsConstructor
public class WebSocketService {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketService.class);

    // 在线列表
    private static final ConcurrentHashMap<String, WebSocketSession> ONLINE_USERS = new ConcurrentHashMap<>();
    private final static String OPEN_ID_KEY = "openId";

    private final AttentionDao attentionDao;
    private final MessageDao messageDao;

    public void online(WebSocketSession session) {
        String openId = this.getOpenId(session);
        if (null != openId && !ONLINE_USERS.containsKey(openId)) {
            ONLINE_USERS.put(openId, session);
        }
    }

    public void send(WebSocketSession session, TextMessage textMessage) {
        try {
            MessageEntity message = JsonUtil.fromJson(new String(textMessage.asBytes()), MessageEntity.class);
        } catch (ServiceException e) {
            e.printStackTrace();
        }
    }

    @Async
    public void send(CommentEntity commentEntity) {
        List<AttentionEntity> list = attentionDao.findByContentId(commentEntity.getContentId());
        MessageEntity messageEntity = new MessageEntity();
        messageEntity.setOpenId(commentEntity.getOpenId());
        messageEntity.setAuthorName(commentEntity.getAuthorName());
        messageEntity.setContentId(commentEntity.getContentId());
        messageEntity.setMessage(commentEntity.getComment());
        messageEntity.setType(MessageTypeEnum.NEARBY_COMMENT);
        for (AttentionEntity attentionEntity : list) {
            String targetOpenId = attentionEntity.getOpenId();
            messageEntity.setTargetOpenId(targetOpenId);
            if (!attentionEntity.getOpenId().equals(messageEntity.getOpenId())) {
                if (ONLINE_USERS.containsKey(targetOpenId)) {
                    try {
                        ONLINE_USERS.get(targetOpenId).sendMessage(new TextMessage(JsonUtil.toJson(messageEntity)));
                    } catch (IOException e) {
                        messageDao.save(messageEntity);
                    } catch (ServiceException e) {
                        logger.error("messageEntity转换失败", e);
                    }
                } else {
                    messageDao.save(messageEntity);
                }
            }
        }
    }

    public void offline(WebSocketSession session) {
        String openId = this.getOpenId(session);
        if (null != openId && ONLINE_USERS.containsKey(openId)) {
            ONLINE_USERS.remove(openId);
        }
    }

    public void error(WebSocketSession session, Throwable ex) {
        logger.error("handleTransportError", ex);
    }

    private String getOpenId(WebSocketSession session) {
        Object o = session.getUri().getQuery();
        return null != o ? o.toString() : null;
    }

}
